﻿package com.designoutput.ui.controls
{
    
    import com.designoutput.event.NumberEvent;
    import com.designoutput.event.SlideControlEvent;
    import com.designoutput.event.SliderEvent;
    import com.designoutput.icon.DropdownOver;
    import com.designoutput.ui.newControls.Slider;
    import com.designoutput.utils.Globals;
    
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.Point;
    import flash.text.*;

    public class Dropslider extends Sprite
    {
		private var _popupVisible:Boolean = false;
		
        private var _min:Number = 0;
		private var _max:Number = 100;
		
        private var _openButton:IconButton;
        private var _slider:Slider;
        private var _disable:Sprite;
		
        private var _popup:Sprite;
		
        private var _numberInput:NumberInput;
		private var _sliderX:Number;
		
        public var value:Number;

        public function Dropslider(width:Number, min:Number, max:Number, defaultVal:Number = 100, sliderX:Number = 88)
        {
            _min = min;
            _max = max;
			_sliderX = sliderX;
			
            value = defaultVal;
			
            if (defaultVal > max)
                value = max;

			_popup = new Sprite();
            _openButton = new IconButton(new DropdownOver(0, 0));
            _numberInput = new NumberInput(width - _openButton.width, defaultVal, min, max);
            _numberInput.addEventListener(NumberEvent.VALUE_CHANGE, this.numberChange);
            addChild(_numberInput);
            _openButton.addEventListener(MouseEvent.MOUSE_DOWN, clickMouseDown, false, 0, true);
            _openButton.x = _numberInput.x + _numberInput.width + 1;
            addChild(_openButton);
            
			drawSlider(defaultVal);
        }

        public function setValue(val:Number) : void
        {
			if(!isNaN(val)){
				this._slider.setValue((val - this._min) / (this._max - this._min));
				this._numberInput.text = val.toString();
				this.value = Number(this._numberInput.text);
			}
        }

        public function disable(dynamic:Boolean = true) : void
        {
            if (this._disable == null)
            {
                this._disable = new Sprite();
                this._disable.visible = false;
                this._disable.alpha = 0.3;
                this._disable.graphics.beginFill(9474192);
                this._disable.graphics.drawRect(0, 0, 10, 10);
                this._disable.graphics.endFill();
                this._disable.height = this._numberInput.height + 1;
                this._disable.width = this._numberInput.width + this._openButton.width + 1;
                this._disable.x = this._numberInput.x;
                this._disable.y = this._numberInput.y;
                addChild(this._disable);
            }
            this._numberInput.type = dynamic ? (TextFieldType.DYNAMIC) : (TextFieldType.INPUT);
            this._disable.visible = dynamic;
        }

        private function drawSlider(defaultVal:Number) : void
        {
            this._popup.filters = [ new DropShadowFilter(2, 45, 0, 0.2, 3, 3, 1, 2) ];
            this._popup.graphics.beginFill(9474192);
            this._popup.graphics.drawRect(0, 0, 117, 23);
            this._popup.graphics.beginFill(13225424);
            this._popup.graphics.drawRect(1, 1, 115, 21);
            this._popup.graphics.endFill();
            this._slider = new Slider(100);
            this._slider.addEventListener(SliderEvent.DRAG, this.sliderDrag);
            this._slider.addEventListener(SliderEvent.RELEASE, this.sliderRelease);
            this._slider.x = 8;
            this._slider.y = 1;
            this._slider.setValue((defaultVal - this._min) / (this._max-this._min));
            this._popup.addChild(this._slider);
        }
		
		protected function sliderDrag(evt:SliderEvent) : void
		{
			if (!evt.manual)
			{
				this._numberInput.text = Math.round(evt.percent * (this._max - this._min) + this._min).toString();
				this.value = Number(this._numberInput.text);
				dispatchEvent(new SlideControlEvent(SlideControlEvent.DRAG, Math.round(evt.percent * (this._max - this._min) + this._min)));
			}
			else
			{
				dispatchEvent(new SlideControlEvent(SlideControlEvent.DRAG, Math.round(evt.percent * (this._max - this._min) + this._min)));
				dispatchEvent(new SlideControlEvent(SlideControlEvent.CHANGE, Math.round(evt.percent * (this._max - this._min) + this._min)));
			}
		}
		
		public function sliderRelease(evt:SliderEvent) : void
		{
			dispatchEvent(new SlideControlEvent(SlideControlEvent.CHANGE, Math.round(evt.percent * (this._max - this._min) + this._min)));
		}

        private function clickMouseDown(evt:MouseEvent) : void
        {
			if(evt.currentTarget == this._openButton){
				if(_popupVisible){
					hidePopup();
				} else {
					showPopup();
				}
			}
        }

       protected function numberChange(evt:NumberEvent) : void
        {
		   var val:Number = new Number(evt.value);
		   if(!isNaN(val)){
			   this._slider.setValue((evt.value - this._min) / (this._max-this._min));
			   this.value = evt.value;
			   dispatchEvent(new SlideControlEvent(SlideControlEvent.DRAG, evt.value));
			   dispatchEvent(new SlideControlEvent(SlideControlEvent.CHANGE, evt.value));
		   }
        }
	   
	   
	   private function clickOutsidePopup(evt:MouseEvent) : void
	   {
		   if (!this._popup.hitTestPoint(evt.stageX, evt.stageY) && !this._openButton.hitTestPoint(evt.stageX, evt.stageY))
			   hidePopup();
	   }

	   protected function showPopup():void {
		   _popupVisible = true;
		   Globals.popupManager.addPopup(this._popup, false);
		   var position:Point = Globals.popupManager.convertPosition(this, new Point(this._openButton.x - _sliderX, 16));
		   this._popup.x = position.x;
		   this._popup.y = position.y;
		   
		   stage.addEventListener(MouseEvent.MOUSE_DOWN, clickOutsidePopup, true);
	   }
	   
	   protected function hidePopup() : void
	   {
		   _popupVisible = false;
		   Globals.popupManager.removePopup(this._popup);
		   
		   stage.removeEventListener(MouseEvent.MOUSE_DOWN, clickOutsidePopup, true);
	   }
    }
}
